import UIKit

//for-in 循环
let minutes = 60
let minuteInerval = 5
//stride(from:A to:B by:C)
//表示 从a(包含)开始到b(不包含B)这个区间内的值  每隔一次c 便打印一次
for tickMark in stride(from: 0, to:minutes , by: minuteInerval) {
    print("stride:\(tickMark)")
}

//stride(from:A through:B by:C)
//表示 从a(包含)开始到b(包含B)这个区间内的值  每隔一次c 便打印一次
for tickMark in stride(from: 0, through: minutes, by: minuteInerval) {
    print("through:\(tickMark)")
}
minutes


//while 循环
//while 循环执行一个合集的语句直到条件变成 false 。这种循环最好在第一次循环之后还有未知数量的遍历时使用。Swift 提供了两种 while 循环：

//while 在每次循环开始的时候计算它自己的条件；
//repeat-while 在每次循环结束的时候计算它自己的条件。

//while用法
let finalSquare = 25
var board = [Int](repeating: 0, count: finalSquare + 1)

board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
var square = 0
var diceRoll = 0
while square < finalSquare {
    // roll the dice
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }
    // move by the rolled amount
    square += diceRoll
    if square < board.count {
        // if we're still on the board, move up or down for a snake or a ladder
        square += board[square]
    }
}
print("Game over!")


//repeat-while 用法
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
repeat {
    // move up or down for a snake or ladder
//    square += board[square]
    // roll the dice
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }
    // move by the rolled amount
    square += diceRoll
} while square < finalSquare
print("Game over!")

//if语句

//switch 语句
let someCharacter:Character = "z"
switch someCharacter {
case "a":
    print("a")
case "b":
    print("b")
case "z":
    print("z")
default:
    print("no found")
}


//多个匹配值
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a", "A":
    print("The letter A")
default:
    print("Not the letter A")
}


//元组 switch用法
let somePoint = (1,1)
switch somePoint {
case (0,0):
    print(somePoint)
case (_,0):
    print(somePoint)
case (0,_):
    print(somePoint)
//   区间匹配
case (-2...2,-2...2):
    print(somePoint)
default:
    print("no found")
}

//绑定值  将匹配的值临时绑定为一个常量或是变量
let anotherPoint = (2,0)
switch anotherPoint {
//    匹配元组第二个元素如果为0  那么letx x 就是第一个元素的值
case (let x,0):
    print(x)
//    同理
case (0,let y):
    print(y)
//   如果所有匹配元素都有绑定值  那么let或是var就可以写在外面
// case let (x,y) ，声明了一个带有两个占位符常量的元组，它可以匹配所有的值
// 所以这个语句中并没有 default  的情况
case let (x,y):
    print(x + y)
}


//  switch  where 分句来检查额外的情况。
let yetAnotherPoint = (1,-1)
switch yetAnotherPoint {
case let (x,y) where x == y:
    print("x=y x:\(x) y:\(y)")
case let (x,y) where x == -y:
    print("x=-y x:\(x) y:\(y)")
case let (x,y):
    print("匹配任何值:\(x),\(y)")
}

// switch 复合情况
// 多个情况出现的时候
// 上面的代码  someCharacter已经赋值为"z"
switch someCharacter {
case"a", "e", "i", "o", "u":
    print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
 "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
    print("\(someCharacter) is a consonant")
//    因为还有其他字符  所以 default 情况匹配其他任意字符。
default:
    print("\(someCharacter) is not a vowel or a consonant")
}

//复合情况下也可以包含绑定值
//理解为 (let distance , 0) 为第一个判断条件
//(0,let distance)  为第二个判断条件
let stillAnotherPoint = (9,0)
switch stillAnotherPoint {
case (let distance , 0),(0,let distance):
    print("distance = \(distance)")
default:
    print("no found")
}

//控制转移语句
//控制转移语句在你代码执行期间改变代码的执行顺序，通过从一段代码转移控制到另一段。
//五种：continue , break , fallthrough , return , throw

//continue  跳出当前循环 重新来过
let puzzleInput = "great mids think alike"
var puzzleOutput = ""
let charactersToRemove:[Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput {
    if charactersToRemove.contains(character) {
        continue
    }else{
        puzzleOutput.append(character)
    }
}
puzzleOutput

//  break  结束循环语句或是控制流语句  switch或是其他循环语句中均可使用break

let numberSymbol:Character = "三"
var possibleIntegerValue:Int?

switch numberSymbol {
case "1", "١", "一", "๑":
    possibleIntegerValue = 1
    print("1")
case "2", "٢", "二", "๒":
    possibleIntegerValue = 2
    print("2")
case "3", "٣", "三", "๓":
    possibleIntegerValue = 3
    print("3")
case "4", "٤", "四", "๔":
    possibleIntegerValue = 4
    print("4")
default:
    print("no found")
}

if let integerValue = possibleIntegerValue {
    print(integerValue)
}else{
    print("is nil")
}


//Fallthrough
//理解为“贯穿到”  一般switch满足了匹配的case就会跳出条件语句
//加上 Fallthrough 之后则不会跳出条件语句  会直接跳到下个条件或是default

let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough
default:
    description += " an integer."
}
//从输出结果可以看出 switch既满足了 case 又 default  所以是“贯穿”了
print(description)


//语句标签
/*
 通过把标签作为关键字放到语句开头来用标签标记一段语句，后跟冒号。
 这里是一个对 while 循环使用标签的栗子，
 这个原则对⚠️所有的循环⚠️和 switch 语句来说都相同：
 
 label name: while condition {
     statements
 }
 
 */
//gameLoop: while square != finalSquare{
//    diceRoll += 1
//    if diceRoll == 7 {
//        diceRoll = 1
//    }
//    switch square + diceRoll {
//    case finalSquare:
//        break gameLoop
//    case let newSquare where newSquare > finalSquare:
//        continue gameLoop
//    default:
//        square += diceRoll
//        square += board[square]
//    }
//}


//⚠️ guard  提前退出

/*
 guard 语句，类似于 if 语句，基于布尔值表达式来执行语句。
 使用 guard 语句来要求一个条件必须是真才能执行 guard 之后的语句。
 与 if 语句不同，
 guard 语句总是有一个 else 分句
 else 分句里的代码会在条件不为真的时候执行。
 */
func greet(person:[String:String]){
    guard let name = person["name"] else {
        print("hello,stranger!")
        return
    }
    print("hello \(name)!")
    
    guard let location = person["location"] else {
        print("I hope the weather is nice near you.")
        return
    }
    print("I hope the weather is nice in \(location)")
    
}

greet(person: ["name":"John"])
greet(person: ["stranger":"stranger"])
greet(person: ["name":"Jane","location":"Cupertino"])


//检查API的可用性
if #available(iOS 10, macOS 10.12, *) {
    print("available iOS 10 表示只在iOS10及以上的才执行 使用iOS10及以上的API")
}else{
    print("使用iOS10以下的API 换句话就是在iOS10以下才会执行")
}
